package com.google.project.client.Operator;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

import com.google.gwt.cell.client.CheckboxCell;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.safehtml.shared.SafeHtmlUtils;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.cellview.client.SimplePager;
import com.google.gwt.user.cellview.client.TextColumn;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FileUpload;
import com.google.gwt.user.client.ui.FormPanel;
import com.google.gwt.user.client.ui.Hidden;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.datepicker.client.DateBox;
import com.google.gwt.view.client.DefaultSelectionEventManager;
import com.google.gwt.view.client.ListDataProvider;
import com.google.gwt.view.client.MultiSelectionModel;
import com.google.project.client.Service.DailyReportService;
import com.google.project.client.Service.DailyReportServiceAsync;
import com.google.project.client.Service.LoginService;
import com.google.project.client.Service.LoginServiceAsync;
import com.google.project.client.Service.ProjTaskService;
import com.google.project.client.Service.ProjTaskServiceAsync;
import com.google.project.client.Service.ProjectService;
import com.google.project.client.Service.ProjectServiceAsync;
import com.google.project.client.Service.UploadService;
import com.google.project.client.Service.UploadServiceAsync;
import com.google.project.shared.CommonFuntion;
import com.google.project.shared.DailyReportDTO;
import com.google.project.shared.DailyReportDetailDTO;
import com.google.project.shared.ProjectDTO;
import com.google.project.shared.ProjectTaskDTO;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.event.dom.client.ChangeEvent;

public class OPTCreateDailyReport extends Composite {

	private static final Binder binder = GWT.create(Binder.class);
	@UiField(provided = true)
	CellTable<DailyReportDetailDTO> ctbReportTaskList = new CellTable<DailyReportDetailDTO>();
	@UiField
	Button btnAddTask;
	@UiField
	Button btnSaveReport;
	@UiField
	Button btnBack;
	@UiField
	ListBox cbTask;
	@UiField
	TextBox txtWorkToFinish;
	@UiField
	TextArea txtContent;
	@UiField
	DateBox dbReportForDate;
	@UiField
	Button btnDelete;
	@UiField
	SimplePager pager;
	@UiField
	TextBox txtProjectName;
	@UiField
	TextBox txtUnit;
	@UiField
	FormPanel formUpload;
	@UiField
	FileUpload fileUpload;
	@UiField
	Hidden forId;
	@UiField
	Hidden type;
	@UiField
	Hidden documentName;
	@UiField Label lblTime;

	final MultiSelectionModel<DailyReportDetailDTO> selectionModel = new MultiSelectionModel<DailyReportDetailDTO>();
	private final LoginServiceAsync loginService = GWT
			.create(LoginService.class);
	private final ProjTaskServiceAsync taskService = GWT
			.create(ProjTaskService.class);
	private final DailyReportServiceAsync dailyReportService = GWT
			.create(DailyReportService.class);
	private final ProjectServiceAsync projectService = GWT
			.create(ProjectService.class);
	private DailyReportDTO currentDailyReportDTO = new DailyReportDTO();
	private final UploadServiceAsync uploadService = GWT
			.create(UploadService.class);
	public String userID = null, currentProjID = "", userName = null;

	List<DailyReportDetailDTO> dailyReportDetailList = new ArrayList<DailyReportDetailDTO>();

	List<ProjectTaskDTO> listTask = new ArrayList<ProjectTaskDTO>();
	interface Binder extends UiBinder<Widget, OPTCreateDailyReport> {
	}

	public OPTCreateDailyReport() {
		initWidget(binder.createAndBindUi(this));
		initCbTask();
		initTable();
		getUserName();
		dbReportForDate.setFormat(new DateBox.DefaultFormat(DateTimeFormat
				.getFormat("dd/MM/yyyy")));
	}

	public OPTCreateDailyReport(String _userID, String _currentProjID) {
		initWidget(binder.createAndBindUi(this));
		this.currentProjID = _currentProjID;
		this.userID = _userID;
		
		projectService.getListTask(_currentProjID, new AsyncCallback<List<ProjectTaskDTO>>() {
			
			@Override
			public void onSuccess(List<ProjectTaskDTO> result) {
				// TODO Auto-generated method stub
				listTask=result;
				initCbTask();
				LoadData(dailyReportDetailList);
			}
			
			@Override
			public void onFailure(Throwable caught) {
				// TODO Auto-generated method stub
				
			}
		});

		initTable();
		getUserName();
		getProjNameByProjID(currentProjID);
		dbReportForDate.setFormat(new DateBox.DefaultFormat(DateTimeFormat
				.getFormat("dd/MM/yyyy")));
		
	}

	// bind data to lblproject
	public void getProjNameByProjID(String id) {
		projectService.getProjectById(id, new AsyncCallback<ProjectDTO>() {

			@Override
			public void onFailure(Throwable caught) {
				// TODO Auto-generated method stub

			}

			@Override
			public void onSuccess(ProjectDTO result) {
				txtProjectName.setText(result.getProjectName());

			}
		});
	}
Boolean checkTask(ProjectTaskDTO data)
{
	String preData = "";
	if(data.getDependent()!=null&&data.getDependent().length()>1)
	{
	
		preData=data.getDependent().substring(0, data.getDependent().indexOf("|"));
	}
	else
	{
		return true;
	}
	if(preData.equals(""))
	{
		return true;
	}
	else
	{
	for(ProjectTaskDTO task : listTask)
	{
		if( CommonFuntion.checkContain(preData, task.getTaskId()+""))
		{
			if(task.getStatus()!=2)
			{
				return false;
			}
		}
	}
	}
	return true;
	}
	// init cbTask, txtUnit
	public void initCbTask() {

		taskService.getTaskByUserID(currentProjID, userID,
				new AsyncCallback<List<ProjectTaskDTO>>() {

					@Override
					public void onSuccess(List<ProjectTaskDTO> result) {
						dbReportForDate.setValue(new Date());
						int count = 0;
						for (ProjectTaskDTO projectTaskDTO : result) {
							// neu tak khong phai task cha , va chua bi close
							// hay hoan thanh
							if (projectTaskDTO.getGroup() == 0
									&& projectTaskDTO.getStatus() != 3
									&& projectTaskDTO.getStatus() != 2) {
								if(checkTask(projectTaskDTO))
								{
									cbTask.addItem(projectTaskDTO.getTaskName(),
											projectTaskDTO.getId());
									if(count==0){
									  txtUnit.setText(projectTaskDTO.getUnit());
									  lblTime.setText("("+CommonFuntion.convertToDate(new Date(projectTaskDTO.getStartDate()))+" - "+CommonFuntion.convertToDate(new Date(projectTaskDTO.getDueDate()))+")");
									count++;
									}
								}
								
							}
						}

					}

					@Override
					public void onFailure(Throwable caught) {
						Window.alert("Có lỗi xảy ra!");

					}
				});

	}

	// init ctbReportTaskList
	public void initTable() {
		// index
		TextColumn<DailyReportDetailDTO> index = new TextColumn<DailyReportDetailDTO>() {
			@Override
			public String getValue(DailyReportDetailDTO object) {
				return object.getIndex() + "";
			}
		};
		// checkbox
		ctbReportTaskList.setSelectionModel(selectionModel,
				DefaultSelectionEventManager
						.<DailyReportDetailDTO> createCheckboxManager());
		Column<DailyReportDetailDTO, Boolean> checkColumn = new Column<DailyReportDetailDTO, Boolean>(
				new CheckboxCell(true, false)) {
			@Override
			public Boolean getValue(DailyReportDetailDTO object) {
				// Get the value from the selection model.
				return selectionModel.isSelected(object);
			}
		};
	
		// task
		TextColumn<DailyReportDetailDTO> taskColumn = new TextColumn<DailyReportDetailDTO>() {
			@Override
			public String getValue(DailyReportDetailDTO object) {
				return object.getTaskName();
			}
		};
		// khoi luong cv hoan thanh
		TextColumn<DailyReportDetailDTO> workToFinishColumn = new TextColumn<DailyReportDetailDTO>() {
			@Override
			public String getValue(DailyReportDetailDTO object) {
				return object.getWorkToFinished().toString() + "("
						+ object.getUnit() + ")";
			}
		};

		// noi dung
		TextColumn<DailyReportDetailDTO> ContentColumn = new TextColumn<DailyReportDetailDTO>() {
			@Override
			public String getValue(DailyReportDetailDTO object) {
				return object.getContent();
			}
		};
		ctbReportTaskList.setWidth("100%", true);
		ctbReportTaskList.setStyleName("ttable");
		ctbReportTaskList.addColumn(checkColumn, SafeHtmlUtils
				.fromSafeConstant("<br/>"));
		ctbReportTaskList.addColumn(index, "STT");
		ctbReportTaskList.setColumnWidth(checkColumn, 40, Unit.PX);
		ctbReportTaskList.setColumnWidth(index, 40, Unit.PX);
		ctbReportTaskList.addColumn(taskColumn, "Công việc");
		ctbReportTaskList.setColumnWidth(taskColumn, 30, Unit.PCT);
		ctbReportTaskList
				.addColumn(workToFinishColumn, "Hoàn thành");
		ctbReportTaskList.setColumnWidth(workToFinishColumn, 20, Unit.PCT);
		ctbReportTaskList.addColumn(ContentColumn, "Nội dung");
		ctbReportTaskList.setColumnWidth(ContentColumn, 40, Unit.PCT);
	}

	protected void LoadData(List<DailyReportDetailDTO> userList) {
		// SimplePager
		// pager.setDisplay(ctbUserList);
		// TODO Auto-generated method stub
		ListDataProvider<DailyReportDetailDTO> dataProvider = new ListDataProvider<DailyReportDetailDTO>();

		// Connect the table to the data provider.
		dataProvider.addDataDisplay(ctbReportTaskList);

		// Add the data to the data provider, which automatically pushes it to
		// the widget
		int index = 1;
		List<DailyReportDetailDTO> list = dataProvider.getList();
		for (DailyReportDetailDTO dailyDetail : userList) {
			dailyDetail.setIndex(index);
			list.add(dailyDetail);
			index++;
		}
		pager.setDisplay(ctbReportTaskList);
		pager.setPageSize(5);
	}

	@UiHandler("btnAddTask")
	void onBtnAddTaskClick(ClickEvent event) {
		boolean flag = true;
		Long createdOnDate = dbReportForDate.getValue().getTime();
		String taskId = cbTask.getValue(cbTask.getSelectedIndex());
		String taskName = cbTask.getItemText(cbTask.getSelectedIndex());
		String content = txtContent.getText();
		String unit = txtUnit.getText();
		if (dailyReportDetailList != null) {
			for (DailyReportDetailDTO reportDetail : dailyReportDetailList) {
				if (reportDetail.getTaskId().equalsIgnoreCase(taskId)) {
					Window
							.alert("Công việc đã tồn tại trong danh sách báo cáo!");
					flag = false;
					break;
				}
			}
		}
		try{
			Double workToFinished = Double.parseDouble(txtWorkToFinish.getText());
			if (flag == true) {
				dailyReportDetailList.add(new DailyReportDetailDTO(taskId,
						taskName, workToFinished, unit, content, createdOnDate));
			}
		}catch(Exception ex){
			Window.alert("Chưa nhập số lượng công việc hoàn thành!");
		}
		

		LoadData(dailyReportDetailList);
		txtContent.setText("");
		txtWorkToFinish.setText("");
	}

	@UiHandler("btnSaveReport")
	void onBtnSaveReportClick(ClickEvent event) {
		int flag = 0;
		if (dbReportForDate.getValue() == null) {
			flag++;
			Window.alert("Bạn chưa nhập ngày muốn báo cáo!");
		}
		if (dbReportForDate.getValue() != null) {
			if (CommonFuntion.removeTime(dbReportForDate.getValue()) > CommonFuntion
					.removeTime(new Date())) {
				Window.alert("Chưa tới ngày báo cáo!");
				flag++;
			}
			if (dailyReportDetailList.size() == 0) {
				Window.alert("Bạn chưa tạo báo cáo ngày!");
				flag++;
			}
		}
		
		if (flag == 0) {
			dailyReportService.checkDateReport(dailyReportDetailList, dbReportForDate.getValue().getTime(), new AsyncCallback<Boolean>() {

				@Override
				public void onFailure(Throwable caught) {
					// TODO Auto-generated method stub
					
				}

				@Override
				public void onSuccess(Boolean result) {
					if(result==true){
						if (Window.confirm("Bạn muốn gửi báo cáo?")) {
							addDailyReport();
						}
					}else{
						Window.alert("Ngày báo cáo nằm ngoài khoảng thời gian công việc tiến hành!");
					}
					
				}
			});
			
		}
	}

	// add DailyReport to database
	public void addDailyReport() {
		getDataToDailyReport();
		dailyReportService.addDailyReport(currentDailyReportDTO, currentProjID,
				dailyReportDetailList, new AsyncCallback<DailyReportDTO>() {

					@Override
					public void onFailure(Throwable caught) {
						Window.alert("Có lỗi xảy ra!");
					}

					@Override
					public void onSuccess(DailyReportDTO result) {
						// upload file
						formUpload.setEncoding(FormPanel.ENCODING_MULTIPART);
						formUpload.setMethod(FormPanel.METHOD_POST);
						forId.setDefaultValue(result.getId());
						type.setDefaultValue("3"); // 3-upload cho dailyReport
						uploadService
								.getBlobStoreUrl(new AsyncCallback<String>() {

									@Override
									public void onSuccess(String result) {
										formUpload.setAction(result.toString());
										formUpload.submit();
										formUpload.reset();
									}

									@Override
									public void onFailure(Throwable caught) {
										caught.printStackTrace();
									}
								});

						Window.alert("Gửi báo cáo thành công!");
						OPTEntrypoint.get().OPTDailyReportList();
					}
				});
	}

	// get dataTo dailyReport
	public void getDataToDailyReport() {
		currentDailyReportDTO.setCreatedOnDate(new Date().getTime());
		currentDailyReportDTO.setFromUserID(userID);
		currentDailyReportDTO.setFromUserName(userName);
		currentDailyReportDTO.setStatus(1); // người nhận chưa đọc
		currentDailyReportDTO.setReportForDate(dbReportForDate.getValue()
				.getTime());
		currentDailyReportDTO.setProjectID(currentProjID);
	}

	// get userName
	public void getUserName() {
		loginService.getUserName(new AsyncCallback<String>() {

			@Override
			public void onFailure(Throwable caught) {
				// TODO Auto-generated method stub

			}

			@Override
			public void onSuccess(String result) {
				userName = result;

			}
		});
	}

	@UiHandler("btnDelete")
	void onBtnDeleteClick(ClickEvent event) {
		Set<DailyReportDetailDTO> listChecked = selectionModel.getSelectedSet();
		List<DailyReportDetailDTO> listDelete = new ArrayList<DailyReportDetailDTO>();

		for (DailyReportDetailDTO dailyReportDetailDTO : listChecked) {
			listDelete.add(dailyReportDetailDTO);
		}

		if (listDelete != null) {
			for (int i = 0; i < listDelete.size(); i++) {
				for (int j = 0; j < dailyReportDetailList.size(); j++) {
					if (listDelete.get(i).getTaskId().equals(
							dailyReportDetailList.get(j).getTaskId())) {
						dailyReportDetailList.remove(j);
					}
				}
			}
			selectionModel.clear();
		} else {
			Window.alert("Bạn chưa chọn để xóa!");
		}

		LoadData(dailyReportDetailList);
	}

	@UiHandler("btnBack")
	void onBtnBackClick(ClickEvent event) {
		OPTEntrypoint.get().OPTDailyReportList();
	}

	@UiHandler("cbTask")
	void onCbTaskChange(ChangeEvent event) {
		fillData();
	}
	public void fillData(){
		taskService.getTaskById(cbTask.getValue(cbTask.getSelectedIndex()), new AsyncCallback<ProjectTaskDTO>() {

			@Override
			public void onFailure(Throwable caught) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onSuccess(ProjectTaskDTO result) {
				txtUnit.setText(result.getUnit());
				lblTime.setText("("+CommonFuntion.convertToDate(new Date(result.getStartDate()))+" - "+CommonFuntion.convertToDate(new Date(result.getDueDate()))+")");
				
			}
		});
	}
}
